format ELF64 executable 3
entry main

RTLD_LAZY = 1
SDL_KEYDOWN = 2
SDL_INIT_VIDEO = 0x00000020
SDL_OPENGL = 0x00000002
SDL_NOFRAME = 0x00000020
SDL_GL_DOUBLEBUFFER = 5
GL_FRAGMENT_SHADER = 0x8B30

PRINT_GLSL_LOG = 0

include 'import64.inc'
interpreter '/lib64/ld-linux-x86-64.so.2'
needed 'libdl.so.2'
import dlopen,dlsym

segment readable executable

main:
    mov rbp,rsp
    sub rsp,2048
    event equ rbp-64
    ;;; load SDL library
    mov rdi,g_str_libsdl
    mov esi,RTLD_LAZY
    call [dlopen]
    mov r12,rax         ; handle to SDL library
    mov r13,[dlsym]     ; pointer to dlsym
    ;;; call SDL_Init
    mov rdi,r12
    mov rsi,g_str_SDL_Init
    call r13
    mov edi,SDL_INIT_VIDEO
    call rax
    ;;; call SDL_GL_SetAttribute
    mov rdi,r12
    mov rsi,g_str_SDL_GL_SetAttribute
    call r13
    mov edi,SDL_GL_DOUBLEBUFFER
    mov esi,1
    call rax
    ;;; call SDL_GL_LoadLibrary
    mov rdi,r12
    mov rsi,g_str_SDL_GL_LoadLibrary
    call r13
    xor edi,edi
    call rax
    ;;; call SDL_SetVideoMode
    mov rdi,r12
    mov rsi,g_str_SDL_SetVideoMode
    call r13
    mov edi,1280
    mov esi,720
    xor edx,edx
    mov ecx,SDL_OPENGL+SDL_NOFRAME
    call rax
    ;;; load SDL_PollEvent
    mov rdi,r12
    mov rsi,g_str_SDL_PollEvent
    call r13
    mov [SDL_PollEvent],rax
    ;;; load SDL_GetTicks
    mov rdi,r12
    mov rsi,g_str_SDL_GetTicks
    call r13
    mov [SDL_GetTicks],rax
    ;;; load SDL_GL_SwapBuffers
    mov rdi,r12
    mov rsi,g_str_SDL_GL_SwapBuffers
    call r13
    mov [SDL_GL_SwapBuffers],rax
    ;;; load SDL_GL_GetProcAddress
    mov rdi,r12
    mov rsi,g_str_SDL_GL_GetProcAddress
    call r13
    mov rbx,rax
    ;;; load glRecti
    mov rdi,g_str_glRecti
    call rbx
    mov [glRecti],rax
    ;;; load glTexCoord1f
    mov rdi,g_str_glTexCoord1f
    call rbx
    mov [glTexCoord1f],rax
    ;;; create GLSL program
    mov rdi,g_str_glCreateShaderProgramv
    call rbx
    mov edi,GL_FRAGMENT_SHADER
    mov esi,1
    mov rdx,g_src_fs_ptr
    call rax
    mov r15d,eax
    ;;; use program
    mov rdi,g_str_glUseProgram
    call rbx
    mov edi,r15d
    call rax
if PRINT_GLSL_LOG = 1
    log equ rbp-2048
    mov rdi,g_str_glGetProgramInfoLog
    call rbx
    mov edi,r15d
    mov esi,1024
    xor edx,edx
    lea rcx,[log]
    call rax
    xor edi,edi
    mov rsi,g_str_printf
    call r13
    mov rdi,g_str_log
    lea rsi,[log]
    call rax
end if
      .main_loop:
    ;;; process window events
    lea rdi,[event]
    call qword [SDL_PollEvent]
    cmp byte [event],SDL_KEYDOWN
    je .main_loop_end
    ;;; get time
    call qword [SDL_GetTicks]
    cvtsi2ss xmm0,eax
    call qword [glTexCoord1f]
    ;;; draw
    mov edi,-1
    mov esi,-1
    mov edx,1
    mov ecx,1
    call qword [glRecti]
    ;;; swap
    call qword [SDL_GL_SwapBuffers]
    jmp .main_loop
      .main_loop_end:
    ;;; call SDL_Quit
    mov rdi,r12
    mov rsi,g_str_SDL_Quit
    call r13
    call rax
    ;;; terminate process
    mov eax,60
    xor edi,edi
    syscall

align 1
g_src_vs:
db  '#version 150 core',10
db  'in vec4 in_vertex;'
db  'void main(){'
db      'gl_Position=in_vertex;'
db  '}',0
g_src_fs:
db  '#version 150 core',10
db  'out vec4 fs_color;'
db  'void main(){'
db      'fs_color=vec4(1);'
db  '}',0

g_str_libsdl db 'libSDL-1.2.so.0',0

g_str_SDL_Init db 'SDL_Init',0
g_str_SDL_Quit db 'SDL_Quit',0
g_str_SDL_SetVideoMode db 'SDL_SetVideoMode',0
g_str_SDL_PollEvent db 'SDL_PollEvent',0
g_str_SDL_GetTicks db 'SDL_GetTicks',0

g_str_SDL_GL_LoadLibrary db 'SDL_GL_LoadLibrary',0
g_str_SDL_GL_GetProcAddress db 'SDL_GL_GetProcAddress',0
g_str_SDL_GL_SetAttribute db 'SDL_GL_SetAttribute',0
g_str_SDL_GL_SwapBuffers db 'SDL_GL_SwapBuffers',0

g_str_glCreateShader db 'glCreateShader',0
g_str_glUseProgram db 'glUseProgram',0

align 8
g_src_vs_ptr dq g_src_vs
g_src_fs_ptr dq g_src_fs
